

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include "planificador.h"
#include "FuncionesPPD.h"
#include "Prueba-ArchConfig.h"
#include "consola.h"

#include "FuncionesPlanificador.h"


/* llamo al planificador
y el toma la lista para que ninguno la modifique mientras planifica.
busca el sector mas cercano al que esta(falta agregar los modulos),
toma el nodo, guarda su contenido, y elimina el nodo de la lista
*/


tInfo* SSTF(){
	tNodo* aux;
	tNodo* devolver;
	tInfo * devolverTInfo;
	int32_t diferencia;
	int32_t pVes=1;



	sem_wait(&semContadorL);
	pthread_mutex_lock(&sem_Lista);

	RecorrerLista(Lista);
		aux= Lista;
		//busco//
		while (aux!= NULL){

			if( (pVes==1)||

			(RestaModulo(aux->Cilindro , CHSActual->Cilindro) < diferencia)){//se saco <= por <

				pVes=0;
				diferencia = RestaModulo(aux->Cilindro , CHSActual->Cilindro);
				devolver= aux;

				}
			aux=aux->Sig;

			}
		if (devolver->Info->Sig == NULL) {
			devolverTInfo = devolver->Info;
			quitarNodo(devolver);
		}
		else{
			devolverTInfo= devolver->Info;
			devolver->Info = devolver->Info->Sig;
		}

//sem_Lista//
	pthread_mutex_unlock(&sem_Lista);
	t_CHS* CHSaux;
	CHSaux=CHSActual;
	div_t cantSectorXDesCil;
	if (timeEntreSector != 0)
		cantSectorXDesCil = div(diferencia ,timeEntreSector );
	else
		cantSectorXDesCil = div(0, 1);
	CHSaux->Sector = CHSActual->Sector + cantSectorXDesCil.quot;
	if (CHSaux->Sector > CHStot->Sector){
			uint32_t sect= CHSaux->Sector - CHStot->Sector -1;
			CHSaux->Sector = sect;
			}


	int32_t timeCil=(diferencia * atoi((char*)archPPD->timeSaltoPista) )/100 ;
	t_CHS *devolverCHS;
	devolverCHS = malloc (sizeof(t_CHS));
	pasaLogicoReal(devolverTInfo->sector, devolverCHS);
	int32_t timeSec=(RestaModulo(CHSaux->Sector,devolverCHS->Sector) * timeEntreSector) /100 ;
	sleep(timeCil + timeSec);
	free(devolverCHS);
	return devolverTInfo;
}



tInfo* SCAN(){
	tInfo* devolverTInfo;
	tNodo* aux;
	int32_t timeEntrePista;
	aux = Lista2;
	while (aux!= NULL){
		if(subiendo == 1){
			if(aux->Cilindro >= CHSActual->Cilindro ){
				if(aux->Cilindro == CHSActual->Cilindro ){
					timeEntrePista =0;
				}
				else{ //en distinto cilindro//
					timeEntrePista= atoi((char*)archPPD->timeSaltoPista) * (RestaModulo(aux->Cilindro, CHSActual->Cilindro));
					t_CHS* CHSaux;
					CHSaux=CHSActual;
					div_t cantSectorXDesCil;
					if(timeEntreSector != 0) cantSectorXDesCil = div(timeEntrePista ,timeEntreSector );
					else cantSectorXDesCil = div( 0 ,1 );
					CHSaux->Sector = CHSActual->Sector + cantSectorXDesCil.quot;
					if (CHSaux->Sector > CHStot->Sector){
						uint32_t sect= CHSaux->Sector - CHStot->Sector -1;
						CHSaux->Sector = sect;
						}
					}
				//saco el primero de la sublista//

				devolverTInfo = aux->Info;

				if(aux->Info->Sig == NULL){
					quitarNodoSCAN(aux);
				}
				else aux->Info= aux->Info->Sig;
				sleep((uint32_t)(timeEntrePista  * atoi((char*)archPPD->timeSaltoPista) )/100  );
				return devolverTInfo;
			}
			aux=aux->Sig;
		}
		else{ //en caso de estar bajando//

			if(aux->Cilindro <= CHSActual->Cilindro ){
				if(aux->Cilindro == CHSActual->Cilindro ){
						timeEntrePista =0;
					}
				else{ //en distinto cilindro//
						timeEntrePista= atoi((char*)archPPD->timeSaltoPista) * ( RestaModulo(aux->Cilindro, CHSActual->Cilindro) );
						t_CHS* CHSaux;
						CHSaux=CHSActual;
						div_t cantSectorXDesCil;
						if(timeEntreSector != 0) cantSectorXDesCil = div(timeEntrePista ,timeEntreSector );
						else cantSectorXDesCil = div( 0 ,1 );
						CHSaux->Sector=CHSActual->Sector + cantSectorXDesCil.quot;
						if (CHSaux->Sector > CHStot->Sector){
							uint32_t sect= CHSaux->Sector - CHStot->Sector -1;
							CHSaux->Sector = sect;
						}
					}
				devolverTInfo = aux->Info;
				if(aux->Info->Sig == NULL){
					quitarNodoSCAN(aux);
				}
				else aux->Info= aux->Info->Sig;

				sleep((uint32_t)(timeEntrePista  * atoi((char*)archPPD->timeSaltoPista) )/100  );
				return devolverTInfo;
			}
			aux=aux->Ant;
		}
	}
	cambiarSentidoScan();
	devolverTInfo = SCAN();

	return devolverTInfo;
}




void quitarNodo(tNodo* Aquitar){

	if(Aquitar->Ant != NULL){
		Aquitar->Ant->Sig = Aquitar->Sig;
	}
	else{
		Lista = Aquitar->Sig;
	}
	if(Aquitar->Sig != NULL){
		Aquitar->Sig->Ant= Aquitar->Ant;
	}
	else{
		ListaRev =Aquitar->Ant;
	}
	if(Lista==NULL) ListaRev = NULL;

	free(Aquitar);
}
void quitarNodoSCAN(tNodo* Aquitar){

	if(Aquitar->Ant != NULL){
		Aquitar->Ant->Sig = Aquitar->Sig;
	}
	else{
		Lista2 = Aquitar->Sig;
	}
	if(Aquitar->Sig != NULL){
		Aquitar->Sig->Ant= Aquitar->Ant;
	}
	else{
		ListaRev2 =Aquitar->Ant;
	}
	if(Lista2==NULL) ListaRev2 = NULL;

	free(Aquitar);
}

void cambiarSentidoScan(){

	if(subiendo == 1){
		subiendo=-1;
		CHSActual->Cilindro = CHStot->Cilindro;
		CHSActual->Sector = CHStot->Sector;
	}
	else{
		subiendo = 1;
		CHSActual->Cilindro =0;
		CHSActual->Sector =0;
	}
	tNodo* AuxCambioSentido;
	AuxCambioSentido = Lista2;
	Lista2= ListaRev2;
	ListaRev2=AuxCambioSentido;

}


int32_t RestaModulo(int32_t numero1, int32_t numero2 ){
	int32_t resultadoPositivo; //Debe ser entero (si la resta da negativo no anda)

	resultadoPositivo = numero1 - numero2;
	if(resultadoPositivo <= 0) resultadoPositivo = resultadoPositivo * (-1);

	return resultadoPositivo;
}




